package org.example.collection.list;

import java.io.*;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Demo1 {
    public static void main(String[] args) {
//        test1();
//        test2();
//        test3();
//        test4();
//        test5();
//        test6();
//        test7();
//        test8();
//        test9();
//        test10();
//        test11();
//        test12();
        test13();
    }

    private static void test13() {
        ArrayList<String> arraylist = new ArrayList<String>(List.of("Hello", "Hi", "Howdy"));
        try {
            FileInputStream fis = new FileInputStream("myfile");
            ObjectInputStream ois = new ObjectInputStream(fis);
            arraylist = (ArrayList) ois.readObject();
            ois.close();
            fis.close();
        } catch(IOException ioe) {
            ioe.printStackTrace();
        } catch(ClassNotFoundException c) {
            System.out.println("Class not found");
            c.printStackTrace();
        }
        System.out.println(arraylist);  // [Hello, Hi, Howdy]
    }

    private static void test12() {
        ArrayList<String> arraylist = new ArrayList<String>(List.of("Hello", "Hi", "Howdy"));
        try {
            FileOutputStream fos= new FileOutputStream("myfile");
            ObjectOutputStream oos= new ObjectOutputStream(fos);
            oos.writeObject(arraylist);
            oos.close();
            fos.close();
        } catch(IOException ioe) {
            ioe.printStackTrace();
        }
    }

    private static void test11() {
        List<Integer> list = new ArrayList<>(List.of(1, 2, 3));
        // 转为Integer数组
        Integer[] integers = list.stream().toArray(Integer[]::new);
        // 转为IntStream在转为数组
        int[] ints = list.stream().mapToInt(Integer::valueOf).toArray();
        System.out.println(Arrays.toString(integers));  // [1, 2, 3]
        System.out.println(Arrays.toString(ints));      // [1, 2, 3]
    }

    private static void test10() {
        List<Integer> list = new ArrayList<>(List.of(1, 2, 3));
        Integer[] integers = new Integer[list.size()];
        Integer[] array = list.toArray(integers);
        System.out.println(Arrays.toString(array));             // [1, 2, 3]
        System.out.println(Arrays.equals(integers, array));     // true
        // 使用空白数组作为参数，在toArray方法中不会用来存储数据，而是创建新的数组，其仅用来确定数组元素类型
        // Integer[] integers = new Integer[0];
        Integer[] integers1 = new Integer[]{};
        Integer[] array1 = list.toArray(integers1);
        System.out.println(Arrays.toString(array1));            // [1, 2, 3]
        System.out.println(Arrays.equals(integers1, array1));   // false
    }

    private static void test9() {
        List<Integer> list = new ArrayList<>(List.of(1, 2, 3));
        Integer[] res = new Integer[list.size()];
        for (int i = 0; i < list.size(); i++) {
            res[i] = list.get(i);
        }
        System.out.println(Arrays.toString(res));
    }

    private static void test8() {
        int[] a = new int[]{1, 2, 3};
        List<Integer> list = Arrays.stream(a).boxed().collect(Collectors.toList());
        System.out.println(list);   // [1, 2, 3]

        long[] b = new long[]{1L, 2L, 3L};
        List<Long> longList = Arrays.stream(b).boxed().collect(Collectors.toList());
        System.out.println(longList);   // [1, 2, 3]

        double[] c = new double[]{1.1, 21.1, 31.1};
        List<Double> doubleList = Arrays.stream(c).boxed().collect(Collectors.toList());
        System.out.println(doubleList);   // [1.1, 21.1, 31.1]

        String[] temp = new String[]{"1", "2", "3"};
        Stream<String> stream = Arrays.stream(temp);
        List<String> list1 = stream.collect(Collectors.toList());
        System.out.println(list1);   // [1, 2, 3]
    }

    private static void test7() {
        String[] temp = new String[]{"asd", "312"};
        List<String> list = new ArrayList<>(temp.length);
        Collections.addAll(list, temp);
        System.out.println(list);   // [asd, 312]
    }

    private static void test6() {
        String[] temp = new String[]{"asd", "312"};
        List<String> list = new ArrayList<>(Arrays.asList(temp));
        list.add("222");
        System.out.println(list);   // [asd, 312, 222]
    }

    private static void test5() {
        String[] temp = new String[]{"asd", "312"};
        List<String> list = Arrays.asList(temp);
//        list.add("ddd");
        System.out.println(list);
    }

    private static void test4() {
        Set<Integer> set = new HashSet<>();
        set.add(1);
        System.out.println(new ArrayList<>(set));       // [1]

        Queue<Integer> queue = new PriorityQueue<>();
        queue.add(1);
        System.out.println(new ArrayList<>(queue));     // [1]

        System.out.println(new ArrayList<>(List.of(1, 2))); // [1, 2]
    }

    private static void test3() {
        //创建集合并添加元素
        List<String> list = new ArrayList<>(List.of("aaa", "bbb", "ccc"));

        // 普通for循环
        // size方法跟get方法还有循环结合的方式，利用索引获取到集合中的每一个元素
        for (int i = 0; i < list.size(); i++) {
            //i:依次表示集合中的每一个索引
            System.out.print(list.get(i) + "\t");
        }
        System.out.println();

        // 迭代器
        Iterator<String> it = list.iterator();
        while (it.hasNext()) {
            System.out.print(it.next() + "\t");
        }
        System.out.println();

        // 列表迭代器
        // 获取一个列表迭代器的对象，里面的指针默认也是指向 0 索引的
        // 额外添加了一个方法：在遍历的过程中，可以添加元素
        ListIterator<String> it1 = list.listIterator();
        while (it1.hasNext()) {
            if ("bbb".equals(it1.next())) {
                it1.add("qqq");
            }
        }
        System.out.println(list);


        // 增强for
        // 下面的变量s，其实就是一个第三方的变量而已。
        // 在循环的过程中，依次表示集合中的每一个元素
        for (String s : list) {
            System.out.print(s + "\t");
        }
        System.out.println();

        // Lambda表达式
        // forEach方法的底层其实就是一个循环遍历，依次得到集合中的每一个元素
        // 并把每一个元素传递给下面的accept方法
        // accept方法的形参s，依次表示集合中的每一个元素
        list.forEach(s -> System.out.print(s + "\t"));
    }

    private static void test2() {
        List<Integer> list1 = List.of(1, 2, 3, 4);
        List<Integer> list2 = new ArrayList<>(List.of(1, 2, 3, 4));
        System.out.println("list1:" + list1.hashCode() + "\tlist2:" + list2.hashCode());
        System.out.println(list1.equals(list2));
        list2.set(0, 2);
        System.out.println("list2:" + list2.hashCode());
        System.out.println(list1.equals(list2));
        /* 输出：
        list1:955331	list2:955331
        true
        list2:985122
        false
         */
    }

    private static void test1() {
        List<Integer> l = new ArrayList<>();
        l.add(2);

        List<Integer> list = new ArrayList<>();
        list.add(4);                    // list的第一个元素
        list.add(5);                    // add(E e)直接添加在list后方
        list.add(0, 3);   // add(int, E) 指定添加到list索引0的位置
        list.addAll(0, l);        // addAll(int, Collection<? extend E>) 指定添加集合到list索引0的位置
        System.out.println(list);       // [2, 3, 4, 5]

        list.set(0, 1);
        System.out.println(list);                   // [1, 3, 4, 5]，set覆盖之前的元素
        System.out.println(list.get(0));            // 1
        System.out.println(list.remove(0));   // 1
        System.out.println(list);                   // [3, 4, 5]

        System.out.println(list.indexOf(2));        // -1
        System.out.println(list.lastIndexOf(5)); // 2

        list.replaceAll(x -> x - 10);     // 对每个元素进行减10操作，得到新的列表
        System.out.println(list);       // [-7, -6, -5]

        list.sort((o1, o2) -> o2 - o1);   // 递减排序
        System.out.println(list);       // [-5, -6, -7]
    }
}
